#include <bits/stdc++.h>
using namespace std;

class AA
{
public:
    int *m_data = nullptr; // 数据成员，指向堆区资源的指针。
    AA() = default; // 启用默认构造函数。
    void alloc()
    {                                   // 给数据成员m_data分配内存。
        m_data = new int;               // 分配内存。
        memset(m_data, 0, sizeof(int)); // 初始化已分配的内存。
    }
    AA(const AA &a)
    {                                     // 拷贝构造函数。
        cout << "调用了拷贝构造函数。\n"; // 显示自己被调用的日志。
        if (m_data == nullptr)
            alloc();                           // 如果没有分配内存，就分配。
        memcpy(m_data, a.m_data, sizeof(int)); // 把数据从源对象中拷贝过来。
    }
    AA(AA &&a)
    {                                     // 移动构造函数。
        cout << "调用了移动构造函数。\n"; // 显示自己被调用的日志。
        if (m_data != nullptr)
            delete m_data;  // 如果已分配内存，先释放掉。
        m_data = a.m_data;  // 把资源从源对象中转移过来。
        a.m_data = nullptr; // 把源对象中的指针置空。
    }
    AA &operator=(const AA &a)
    {                                 // 赋值函数。
        cout << "调用了赋值函数。\n"; // 显示自己被调用的日志。
        if (this == &a)
            return *this; // 避免自我赋值。
        if (m_data == nullptr)
            alloc();                           // 如果没有分配内存，就分配。
        memcpy(m_data, a.m_data, sizeof(int)); // 把数据从源对象中拷贝过来。
        return *this;
    }
    AA &operator=(AA &&a)
    {                                     // 移动赋值函数。
        cout << "调用了移动赋值函数。\n"; // 显示自己被调用的日志。
        if (this == &a)
            return *this; // 避免自我赋值。
        if (m_data != nullptr)
            delete m_data;  // 如果已分配内存，先释放掉。
        m_data = a.m_data;  // 把资源从源对象中转移过来。
        a.m_data = nullptr; // 把源对象中的指针置空。
        return *this;
    }
    ~AA()
    { // 析构函数。
        if (m_data != nullptr)
        {
            delete m_data;
            m_data = nullptr;
        }
    }
};
int main()
{
    AA a1;          // 创建对象a1。
    a1.alloc();     // 分配堆区资源。
    *a1.m_data = 3; // 给堆区内存赋值。
    cout << "a1.m_data=" << *a1.m_data << endl;
    AA a2 = a1; // 将调用拷贝构造函数。
    cout << "a2.m_data=" << *a2.m_data << endl;
    AA a3;
    a3 = a1; // 将调用赋值函数。
    cout << "a3.m_data=" << *a3.m_data << endl;
    auto f = []
    { AA aa; aa.alloc(); *aa.m_data = 8; return aa; };         // 返回AA类对象的lambda函数。
    AA a4 = f(); // lambda函数返回临时对象，是右值，将调用移动构造函数。
    cout << "a4.m_data=" << *a4.m_data << endl;
    AA a6;
    a6 = f(); // lambda函数返回临时对象，是右值，将调用移动赋值函数。
    cout << "a6.m_data=" << *a6.m_data << endl;
}